package com.longway.core.toolbox.wdp.api;

import java.io.Serializable;
import java.util.Map;

import com.jfinal.kit.JsonKit;
import com.longway.core.toolbox.utils.RetryUtils.ResultCheck;


@SuppressWarnings("unchecked")
public class PreAuthCode implements ResultCheck, Serializable {
	private static final long serialVersionUID = -6700763400653625689L;
	private String pre_auth_code;
    private Integer expires_in;
    private Integer errcode;
    private String errmsg;
    private Long expiredTime;
    private String json;

    public PreAuthCode(String jsonStr) {
        this.json = jsonStr;

        try {
            Map<String, Object> temp = JsonKit.parse(jsonStr, Map.class);
            pre_auth_code = (String) temp.get("pre_auth_code");
            expires_in = (Integer) temp.get("expires_in");
            errcode = (Integer) temp.get("errcode");
            errmsg = (String) temp.get("errmsg");

            if (expires_in != null) {
            	// expires_in - 9  用于控制在 component_access_token 过期之前 9 秒就 "主动" 再次获取component_access_token
            	// 避免大并发场景下多线程同时获取component_access_token，造成公众平台 api 调用额度的浪费
                expiredTime = System.currentTimeMillis() + ((expires_in - 9) * 1000);
            }
            
            // 用户缓存时还原
            if (temp.containsKey("expiredTime")) {
                 expiredTime = (Long) temp.get("expiredTime");
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String getJson() {
        return json;
    }

    public String getCacheJson() {
        Map<String, Object> temp = JsonKit.parse(json, Map.class);
        temp.put("expiredTime", expiredTime);
        temp.remove("expires_in");
        return JsonKit.toJson(temp);
    }

    public boolean isAvailable() {
        if (expiredTime == null) {
            return false;
        }
        if (errcode != null) {
            return false;
        }
        if (expiredTime < System.currentTimeMillis()) {
            return false;
        }
        return pre_auth_code != null;
    }

    public Integer getExpiresIn() {
        return expires_in;
    }

    public Long getExpiredTime() {
        return expiredTime;
    }

    public Integer getErrorCode() {
        return errcode;
    }

    public String getErrorMsg() {
        if (errcode != null) {
            String result = ReturnCode.get(errcode);
            if (result != null) {
                return result;
            }
        }
        return errmsg;
    }

    public String getPreAuthCode() {
		return pre_auth_code;
	}

	@Override
    public boolean matching() {
        return isAvailable();
    }
}
